package ldh.common.testui.component;

import com.jfoenix.controls.*;
import com.jfoenix.validation.RequiredFieldValidator;
import com.jfoenix.validation.base.ValidatorBase;
import javafx.application.Platform;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.stage.Modality;
import javafx.util.Pair;
import ldh.common.testui.constant.ParamType;
import ldh.common.testui.dao.TestHttpParamDao;
import ldh.common.testui.model.TestHttp;
import ldh.common.testui.model.TestHttpParam;
import ldh.common.testui.util.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.sql.SQLException;
import java.util.*;

/**
 * Created by ldh123 on 2017/6/21.
 */
public class HttpParamControl extends HBox {

    private static final Logger LOGGER = LoggerFactory.getLogger(HttpParamControl.class);

    @FXML private TableView<TestHttpParam> tableView;
    @FXML private TableColumn<TestHttpParam, Boolean> checkBoxTableColumn;
    @FXML private TableColumn<TestHttpParam, String> keyTableColumn;
    @FXML private TableColumn<TestHttpParam, String> valueTableColumn;

    private TestHttp testHttp;
    private ParamType paramType;
    private ObservableList<TestHttpParam> tableValues = FXCollections.observableArrayList();

    public HttpParamControl() throws IOException {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/control/fxml/HttpParam.fxml"));
        loader.setRoot(this);
        loader.setController(this);
        loader.load();

        tableView.setItems(tableValues);
    }

    @FXML
    public void initialize() {
        tableView.setEditable(true);
        checkBoxTableColumn.setCellFactory(CheckBoxTableCell.forTableColumn(checkBoxTableColumn));
        checkBoxTableColumn.setStyle("-fx-alignment:center");

        keyTableColumn.setCellFactory(TextFieldTableCell.forTableColumn());
        valueTableColumn.setCellFactory(TextFieldTableCell.forTableColumn());
        keyTableColumn.setOnEditCommit(h->{
            String newValue = h.getNewValue();
            if (StringUtils.isEmpty(newValue)) {
                DialogUtil.alert("不能为空", Alert.AlertType.WARNING);
                tableView.refresh();
                return;
            }
            TestHttpParam testHttpParam = h.getRowValue();
            testHttpParam.setName(newValue);
            save(testHttpParam);
            refresh();
        });

        valueTableColumn.setOnEditCommit(h->{
            String newValue = h.getNewValue();
            TestHttpParam testHttpParam = h.getRowValue();
            testHttpParam.setContent(newValue);
            save(testHttpParam);
            refresh();
        });

        tableValues.addListener((ListChangeListener) c->{
            while(c.next()) {
                if (c.wasAdded()) {
                    List<TestHttpParam> testHttpParamList = c.getAddedSubList();
                    testHttpParamList.forEach(testHttpParam -> {
                        testHttpParam.enableProperty().addListener((b, o, n)->updateTestHttpParam(testHttpParam));
                    });
                }
            }

        });
    }

    public ObservableList<TestHttpParam> getData() {
        return tableView.getItems();
    }

    public void initData(TestHttpParam testHttpParam) {
        tableValues.add(testHttpParam);
    }

    public void setTestHttp(TestHttp testHttp) {
        this.testHttp = testHttp;
    }

    public void setParamType(ParamType paramType) {
        this.paramType = paramType;
    }

    @FXML public void add() {
        if (testHttp == null) {
            DialogUtil.alert("请输入http地址", Alert.AlertType.ERROR);
            return;
        }
        List<ValidatorBase> validatorBases = new ArrayList();

        GridPane grid = new GridPane();
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(20, 10, 10, 10));

        JFXTextField keyTextField = new JFXTextField();
        RequiredFieldValidator keyValidator = JFoenixUtil.createValidatorBase(new RequiredFieldValidator(), keyTextField);
        keyTextField.getValidators().add(keyValidator);
        validatorBases.add(keyValidator);

        JFXTextArea valueTextArea = new JFXTextArea();
        valueTextArea.setPrefRowCount(4);
//        RequiredFieldValidator valueValidator = JFoenixUtil.createValidatorBase(new RequiredFieldValidator(), valueTextArea);
//        validatorBases.add(valueValidator);

        Label keyLabel = new Label("Key:");
        grid.add(keyLabel, 0, 0);
        grid.add(keyTextField, 1, 0);

        Label valueLabel = new Label("Value:");
        grid.add(valueLabel, 0, 1);
        grid.add(valueTextArea, 1, 1);

        ColumnConstraints columnConstraints1 = new ColumnConstraints(100);
        columnConstraints1.setHalignment(HPos.RIGHT);
        ColumnConstraints columnConstraints2 = new ColumnConstraints(100, 400, 1000, Priority.ALWAYS, HPos.LEFT, true);
        grid.getColumnConstraints().addAll(columnConstraints1, columnConstraints2);

        JFXAlert dialog = DialogUtil.createModelDialog(grid, "增加参数", (jfxAlert, jfxDialogLayout) -> {
            JFXButton saveButton = new JFXButton("Add");
            saveButton.getStyleClass().add("dialog-accept");
            saveButton.setOnAction(event -> {
                validatorBases.forEach(validatorBase -> validatorBase.validate());
                long errorCount = validatorBases.stream().filter(validatorBase -> validatorBase.getHasErrors()).count();
                if(errorCount > 0) {
                    DialogUtil.alert("请按要求填写", Alert.AlertType.ERROR);
                    return;
                }
                TestHttpParam testHttpParam = new TestHttpParam();
                testHttpParam.setName(keyTextField.getText().trim());
                testHttpParam.setContent(valueTextArea.getText().trim());
                testHttpParam.setParamType(paramType);
                testHttpParam.setTestHttpId(testHttp.getId());
                testHttpParam.enableProperty().setValue(true);
                save(testHttpParam);
                tableValues.add(testHttpParam);
                refresh();
                jfxAlert.close();
            });
            return Arrays.asList(saveButton);
        });

        dialog.show();
    }

    @FXML public void edit() {
        if (testHttp == null) {
            DialogUtil.alert("请输入http地址", Alert.AlertType.ERROR);
            return;
        }
        TestHttpParam httpParam = tableView.getSelectionModel().getSelectedItem();
        if (httpParam == null) {
            DialogUtil.alert("请选择一行需要修改的数据", Alert.AlertType.ERROR);
            return;
        }

        List<ValidatorBase> validatorBases = new ArrayList();
        GridPane grid = new GridPane();
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(20, 20, 10, 10));

        JFXTextField keyTextField = new JFXTextField();
        keyTextField.setText(httpParam.getName());
        RequiredFieldValidator keyValidator = JFoenixUtil.createValidatorBase(new RequiredFieldValidator(), keyTextField);
        validatorBases.add(keyValidator);

        JFXTextArea valueTextArea = new JFXTextArea();
        valueTextArea.setPrefRowCount(4);
        valueTextArea.setText(httpParam.getContent());
        RequiredFieldValidator valueValidator = JFoenixUtil.createValidatorBase(new RequiredFieldValidator(), valueTextArea);
        validatorBases.add(valueValidator);

        grid.add(new Label("Key:"), 0, 0);
        grid.add(keyTextField, 1, 0);
        grid.add(new Label("Value:"), 0, 1);
        grid.add(valueTextArea, 1, 1);

        ColumnConstraints columnConstraints1 = new ColumnConstraints(100);
        columnConstraints1.setHalignment(HPos.RIGHT);
        ColumnConstraints columnConstraints2 = new ColumnConstraints(100, 400, 1000, Priority.ALWAYS, HPos.LEFT, true);
        grid.getColumnConstraints().addAll(columnConstraints1, columnConstraints2);

        JFXAlert dialog = DialogUtil.createModelDialog(grid, "修改参数", (jfxAlert, jfxDialogLayout) -> {
            JFXButton saveButton = new JFXButton("Add");
            saveButton.getStyleClass().add("dialog-accept");
            saveButton.setOnAction(event -> {
                validatorBases.forEach(validatorBase -> validatorBase.validate());
                long errorCount = validatorBases.stream().filter(validatorBase -> validatorBase.getHasErrors()).count();
                if(errorCount > 0) {
                    DialogUtil.alert("请按要求填写", Alert.AlertType.ERROR);
                    return;
                }
                httpParam.setName(keyTextField.getText().trim());
                httpParam.setContent(valueTextArea.getText().trim());
                httpParam.setParamType(paramType);
                httpParam.setTestHttpId(testHttp.getId());
                save(httpParam);
                refresh();
                jfxAlert.close();
            });
            return Arrays.asList(saveButton);
        });


        dialog.show();
    }

    private void save(TestHttpParam testHttpParam) {
        try {
            TestHttpParamDao.save(testHttpParam);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @FXML public void remove() {
        TestHttpParam keyValue = tableView.getSelectionModel().getSelectedItem();
        if (keyValue != null) {
            try {
                TestHttpParamDao.delete(keyValue);
            } catch (Exception e) {
                e.printStackTrace();
            }

            tableValues.remove(keyValue);
        } else {
            DialogUtil.alert("请选择一行需要删除的数据", Alert.AlertType.ERROR);
        }
    }

    public void changeContentType(String contentType) {
        for (TestHttpParam httpParam : tableValues) {
            if (httpParam.getName().equals("contentType")) {
                httpParam.setContent(contentType);
                refresh();
                return;
            }
        }
        TestHttpParam httpParam = new TestHttpParam();
        httpParam.setName("contentType");
        httpParam.setContent(contentType);
        httpParam.setParamType(paramType);
        tableValues.add(httpParam);
        refresh();
    }

    private void refresh() {
        tableView.setItems(tableValues);
        System.out.println("size: " + tableValues.size());
        tableView.refresh();
    }

    public Map<String, Object> getAllParams() {
        Map<String, Object> allParams = new HashMap<>();
        for(TestHttpParam keyValue : tableView.getItems() ) {
            allParams.put(keyValue.getName(), keyValue.getContent());
        }
        return allParams;
    }

    private void updateTestHttpParam(TestHttpParam testHttpParam) {
        ThreadUtilFactory.getInstance().submit(()->{
            try {
                TestHttpParamDao.update(testHttpParam);
                LOGGER.info("updateTestHttpParam!!!!");
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }, null);

    }

}
